package com.lifesting.book.wci;

/**
 * 不考虑溢出问题
 * 
 * @author yifan.cby
 * 
 */
public final class ValueComputer {

	public static Object computerToken(PascalAntlrToken ot) {
		switch (ot.getType()) {
		case PascalLexer.NUMBER:
			return computeInt(ot.getText());
		case PascalLexer.NUMBER_REAL:
			return computeFloat(ot.getText());
		case PascalLexer.STRING:
			return computeString(ot.getText());
		}

		return null;
	}

	public static String computeString(String text) {
		return text.replace("''", "'").replaceAll("(\r\n?)|\n", " ");
	}

	public static double computeFloat(String text) {
		if (text==null && (text = text.trim()).length() < 1)
				return 0.0f;
		else{
			String wd = null,fd = null,ed = null;
			char sign = '+';
			boolean has_dot =false;
			boolean has_e = false;
			StringBuffer buffer = new StringBuffer();
			for (int i = 0; i < text.length(); i++){
				char cc = text.charAt(i);
				switch (cc){
				case '.':
					wd = buffer.toString();
					buffer.setLength(0);
					has_dot = true;
					break;
				case 'E':
				case 'e':
					if (has_dot){
						fd = buffer.toString();
					}else{
						wd = buffer.toString();
					}
					buffer.setLength(0);
					has_e = true;
					break;
				case '+':
				case '-':
					sign = cc;
					break;
				default:
					buffer.append(cc);
					break;
				}
			}
			if (wd == null){
				wd = buffer.toString();
			}else{
				if (has_e) ed = buffer.toString();
				else fd = buffer.toString();
			}
			System.out.println(wd+"."+fd+"E"+sign+ed);
			return computeFloatValue(wd, fd, ed, sign);
		}
	}

	public static Integer computeInt(String text) {
		return Integer.valueOf(text);
	}

	private static double computeFloatValue(String wholeDigits, String fractionDigits,
			String exponentDigits, char exponentSign) {
		double floatValue = 0.0;
		int exponentValue = exponentDigits != null ? Integer.parseInt(exponentDigits) : 0;
		String digits = wholeDigits;

		if (exponentSign == '-') {
			exponentValue = -exponentValue;
		}

		if (fractionDigits != null) {
			exponentValue -= fractionDigits.length();
			digits += fractionDigits;
		}

		int index = 0;
		while (index < digits.length()) {
			floatValue = 10 * floatValue
					+ Character.getNumericValue(digits.charAt(index++));
		}
		if (exponentValue != 0) {
			floatValue *= Math.pow(10, exponentValue);
		}

		return  floatValue;
	}

}
